package cmd

import (
	"cobra-viper-demo/config"
	"fmt"
	"github.com/fsnotify/fsnotify"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var Verbose bool
var Source string
var Region string
var CfgFile string

func RootCmd() *cobra.Command {
	// 初始化配置文件
	cobra.OnInitialize(initConfig)

	var rootCmd = &cobra.Command{
		Use:   "cli",
		Short: "cli命令行简短描述",
		Long:  `cli命令的详细说明`,
		// 子命令同样执行
		PersistentPreRun: func(cmd *cobra.Command, args []string) {
			fmt.Println("cli PersistentPreRun")
		},
		// 子命令不执行
		PreRun: func(cmd *cobra.Command, args []string) {
			fmt.Println("cli PreRun")
		},
		PreRunE: func(cmd *cobra.Command, args []string) error {
			fmt.Println("cli PreRunE")

			// return errors.New("PreRunE err")
			return nil
		},
		// 执行函数
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("run cli...")
			fmt.Printf("Source: %v\n", Source)
			fmt.Printf("Verbose: %v\n", Verbose)
			fmt.Printf("Region: %v\n", Region)
			fmt.Printf("Author: %v\n", viper.Get("author"))
			fmt.Printf("Config: %v\n", viper.AllSettings())
		},
		// 子命令不执行
		PostRun: func(cmd *cobra.Command, args []string) {
			fmt.Println("cli PostRun")
		},
		// 子命令同样执行
		PersistentPostRun: func(cmd *cobra.Command, args []string) {
			fmt.Println("cli PersistentPostRun")
		},
		// 解析本地标志  传递到子命令
		TraverseChildren: true,
	}
	// 全局配置参数
	rootCmd.PersistentFlags().StringVarP(&CfgFile, "config", "c", "./config.yaml", "config file")
	//rootCmd.MarkPersistentFlagRequired("config") // 必选参数

	rootCmd.AddCommand(NewMysqlCmd())

	// 必选标志
	//rootCmd.MarkFlagRequired("source")

	// 必选标志
	//rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
	//rootCmd.MarkFlagRequired("region")

	rootCmd.AddCommand(PrintCmd())
	rootCmd.AddCommand(VersionCmd())

	return rootCmd
}

// go run main.go mysql a  -c ./config2.yaml
func initConfig() {
	if CfgFile != "" {
		// 指定配置文件路径
		viper.SetConfigFile(CfgFile)
	} else {
		homedir, _ := os.Getwd()
		// home, err := homedir.Dir()
		// 查找配置文件所在的路径 可以配置多个
		viper.AddConfigPath(homedir + "/config")
		viper.AddConfigPath(".")
		viper.AddConfigPath("/etc/container")

		// 配置文件名称(无扩展名)
		viper.SetConfigName("config")

	}
	// 如果配置文件的名称中有扩展名，则需要配置此项
	viper.SetConfigType("yaml")

	// 查找并读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		fmt.Println("Can't read config:", err)
		os.Exit(1)
	}
	viper.WatchConfig()

	viper.OnConfigChange(func(e fsnotify.Event) {
		fmt.Println("configPath file changed:", e.Name)
		if err := viper.Unmarshal(&config.ServerConfig); err != nil {
			fmt.Println(err)
		}
	})
	if err := viper.Unmarshal(&config.ServerConfig); err != nil {
		panic(err)
	}
}
